package com.example.socket.client;

import com.example.socket.core.*;
import com.example.socket.handler.Processor;
import com.example.socket.handler.TypeDefinition;

/**
 * 客户端接口
 */
public interface Client {

    public static final int TCP = 1;
    public static final int KCP = 2;


    /**
     * 注册指令{@link Command}对应的处理器{@link Processor}和消息体定义{@link TypeDefinition}
     * @param command 指令
     * @param definition 消息体定义
     * @param processor 处理器
     * @throw {@link IllegalStateException} 重复注册时会抛出
     */
    void register(Command command, TypeDefinition definition, Processor<?, ?> processor);

    /**
     * 注册通讯接口/类
     * @param clz
     * @throw {@link IllegalStateException} 重复注册时会抛出
     */
    void registerInterface(Class<?> clz);

    /**
     * 以默认编码格式发送请求
     * @param message 消息
     * @param resend 是否失败重发
     * @param future
     * @param <O>
     * @return
     */
    <O> SocketFuture<Response<O>> send(Message message, boolean resend, SocketFuture<Response<O>> future);

    /**
     * 发送请求并接收回应
     * @param request 请求对象
     * @param type 返回类型
     * @param resend是否失败重发
     * @return
     */
    <I, O> SocketFuture<Response<O>> send(Request<I> request, Class<O> type, boolean resend);

    /**
     * 以默认编码格式发送请求
     * @param request
     * @param resend
     * @param <I>
     * @param <O>
     * @return
     */
    <I, O> SocketFuture<Response<O>> send(Request<I> request, boolean resend);

    /**
     * 发送请求并接收回应
     * @param request
     * @param callback
     * @param resend
     * @param <I>
     * @param <O>
     * @return
     */
    <I, O> SocketFuture<Response<O>> send(Request<I> request, SocketCallback<Response<O>> callback, boolean resend);

    /**
     * 简单发送
     * @param message
     * @param resend
     */
    void send(Message message, boolean resend);

    /**
     * 获取推送代理
     * @param clz 代理的推送接口
     * @param sessions SESSION
     * @return
     */
    <T> T getSendProxy(Class<T> clz);

    /**
     * 关闭与服务器的连接
     */
    void close();

    /**
     * 连接服务器
     */
    void connect();

    /**
     * 检查是否需要保持连接
     * @return
     */
    boolean isKeepAlive();

    /**
     * 获取客户端的最后操作时间戳
     * @return
     */
    long getTimestamp();

    /**
     * 检查会话是否处于连接状态
     * @return
     */
    boolean isConnected();

    /**
     * 连接是否有效
     * @return
     */
    boolean isDisposed();

    /**
     * 是否空闲
     * @return
     */
    boolean isIdle();

    /**
     * 取消保持连接状态
     */
    void disableKeepAlive();

    /**
     * 获取连接的地址
     * @return
     */
    String getAddress();

    /**
     * 修改该客户端的
     * @param sessionId
     */
    void setSessionId(long sessionId);

    /**
     * 是否发送心跳
     * @return
     */
    boolean isSendHeartBeat();

    /**
     * 获取 Session
     * @return
     */
    Session getSession();

}
